package com.gin.no_gay_alliance.viewmodel.notice;

import com.gin.jackson.utils.ObjectUtils;
import com.gin.nga.response.field.NoticeData;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 提醒消息
 *
 * @author : ginstone
 * @version : v1.0.0
 * @since : 2023/9/11 10:22
 **/
public class NoticeDataModel {
    public ArrayList<ReplyNoticeModel> replyNotices = new ArrayList<>();
    public ArrayList<MessageNoticeModel> msgNotices = new ArrayList<>();
    public ArrayList<RecommendNoticeModel> recommendNotices = new ArrayList<>();
    /**
     * 获得时间
     */
    public long timestamp;

    /**
     * 下一次执行请求带的time参数
     */
    public long nextTime;

    public NoticeDataModel() {
    }

    public NoticeDataModel(NoticeData noticeData) {
        this.timestamp = noticeData.getTimestamp() != null ? noticeData.getTimestamp().toEpochSecond() : 0;

        if (!ObjectUtils.isEmpty(noticeData.getReplyNotices())) {
            replyNotices = noticeData.getReplyNotices().stream().map(ReplyNoticeModel::new).collect(Collectors.toCollection(ArrayList::new));
        }
        if (!ObjectUtils.isEmpty(noticeData.getMsgNotices())) {
            msgNotices = noticeData.getMsgNotices().stream().map(MessageNoticeModel::new).collect(Collectors.toCollection(ArrayList::new));
        }
        if (!ObjectUtils.isEmpty(noticeData.getRecommendNotices())) {
            recommendNotices = noticeData.getRecommendNotices().stream().map(RecommendNoticeModel::new).collect(Collectors.toCollection(ArrayList::new));
        }

        calculateNextTime();
    }

    /**
     * 合并数据
     *
     * @param that 待合并的数据
     */
    public void merge(NoticeDataModel that) {
        this.replyNotices = mergeList(this.replyNotices, that.replyNotices);
        this.msgNotices = mergeList(this.msgNotices, that.msgNotices);
        this.recommendNotices = mergeList(this.recommendNotices, that.recommendNotices);

        this.timestamp = that.timestamp;

        calculateNextTime();
    }

    /**
     * 统计未读数量
     *
     * @return 未读数量
     */
    public long countUnread() {
        long count = 0;
        if (!ObjectUtils.isEmpty(replyNotices)) {
            count += BaseNoticeModel.countUnread(replyNotices);
        }
        if (!ObjectUtils.isEmpty(msgNotices)) {
            count += BaseNoticeModel.countUnread(msgNotices);
        }
        if (!ObjectUtils.isEmpty(recommendNotices)) {
            count += BaseNoticeModel.countUnread(recommendNotices);
        }
        return count;
    }

    /**
     * 清空数据
     */
    public void clear() {
        this.replyNotices = new ArrayList<>();
        this.msgNotices = new ArrayList<>();
        this.recommendNotices = new ArrayList<>();
    }

    /**
     * 全部已读
     */
    public void readAll() {
        BaseNoticeModel.readAll(replyNotices);
        BaseNoticeModel.readAll(msgNotices);
        BaseNoticeModel.readAll(recommendNotices);
    }

    /**
     * 总消息数
     *
     * @return
     */
    public int count() {
        return count(recommendNotices) + count(msgNotices) + count(replyNotices);
    }

    /**
     * 计算下一次请求的time参数
     */
    private void calculateNextTime() {
        final long t0 = this.replyNotices.stream().mapToLong(i -> i.timestamp).max().orElse(0);
        final long t1 = this.msgNotices.stream().mapToLong(i -> i.timestamp).max().orElse(0);
        final long t2 = this.recommendNotices.stream().mapToLong(i -> i.timestamp).max().orElse(0);

        final long[] longs = {t0, t1, t2, timestamp};
        this.nextTime = Arrays.stream(longs).max().getAsLong();
    }

    private static <T extends BaseNoticeModel<?>> ArrayList<T> mergeList(List<T> oldData, List<T> newData) {
        ArrayList<T> res = new ArrayList<>();
        if (!ObjectUtils.isEmpty(oldData)) {
            res.addAll(oldData);
        }
        if (!ObjectUtils.isEmpty(newData)) {
            res.addAll(newData);
        }
        return res;
    }

    private static int count(List<?> list) {
        return list == null ? 0 : list.size();
    }

}
